// Copyright (c) Microsoft Corporation. All rights reserved.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Xml.Serialization;

using Microsoft.TeamFoundation.Migration.Toolkit.Wit;
using Microsoft.TeamFoundation.WorkItemTracking.Client;

namespace Microsoft.TeamFoundation.Migration.Toolkit.Linking
{
    /// <summary>
    /// Work item link.
    /// </summary>
    [Serializable]
    public abstract class WorkItemLink : ILink
    {
        private string m_sourceUri;                         // Source artifact
        private string m_targetUri;                         // Target artifact
        private string m_comment;                           // Comment

        /// <summary>
        /// Parameterless constructor for serialization.
        /// </summary>
        protected WorkItemLink()
        {
        }

        /// <summary>
        /// Gets/sets source artifact's URI.
        /// </summary>
        [XmlIgnore]
        public string SourceUri 
        { 
            get { return m_sourceUri; }
            set
            {
                if (string.IsNullOrEmpty(value))
                {
                    throw new ArgumentNullException("value");
                }
                m_sourceUri = value;
            }
        }

        /// <summary>
        /// Gets/sets target artifact's URI.
        /// </summary>
        [XmlIgnore]
        public string TargetUri
        {
            get { return m_targetUri; }
            set
            {
                if (string.IsNullOrEmpty(value))
                {
                    throw new ArgumentNullException("value");
                }
                m_targetUri = value;
            }
        }
        public string Comment { get { return m_comment; } }

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="sourceUri">Source artifact</param>
        /// <param name="comment">Link's comment</param>
        protected WorkItemLink(
            string sourceUri,
            string targetUri,
            string comment)
        {
            if (string.IsNullOrEmpty(sourceUri))
            {
                throw new ArgumentNullException("sourceUri");
            }
            if (string.IsNullOrEmpty(targetUri))
            {
                throw new ArgumentNullException("targetUri");
            }
            m_sourceUri = sourceUri;
            m_targetUri = targetUri;
            m_comment = comment;
        }

        /// <summary>
        /// Copy constructor.
        /// </summary>
        /// <param name="src">Source link</param>
        protected WorkItemLink(
            WorkItemLink src)
        {
            if (src == null)
            {
                throw new ArgumentNullException("src");
            }
            m_sourceUri = src.m_sourceUri;
            m_targetUri = src.m_targetUri;
            m_comment = src.m_comment;
        }

        #region ILink Members

        [XmlIgnore]
        public string LinkType { get { return GetType().FullName; } }

        public abstract ILink Redirect(
            string targetUri);

        public abstract void UpdateTfs(
            AssociationAction action,
            object target);

        public virtual string Serialize()
        {
            XmlSerializer s = new XmlSerializer(GetType());
            using (MemoryStream stream = new MemoryStream())
            {
                s.Serialize(stream, this);
                stream.Seek(0, SeekOrigin.Begin);
                using (StreamReader reader = new StreamReader(stream))
                {
                    return reader.ReadToEnd();
                }
            }
        }

        #endregion
    }
}
